#include "game.h"
#include "loc/rva.h"
#include <ranges>

using namespace std;

uint32 Game::get_taxi_node_id(uint32 index) {
  return r4(r8(base_ + RVA_TAXI_NODE_ID_ARR_BASE) + index * 0x28);
}

uint32 Game::get_num_taxi_nodes() {
  return r4(base_ + RVA_TAXI_NODE_ID_ARR_BASE - 0x30);
}

std::string Game::get_taxi_node_name_ex(uint32 node_id) {
  uint64 addr{base_ + RVA_TAXI_NODE_NAME_CALL};
  uint64 rcx{base_ + RVA_TAXI_NODE_ARR_BASE};
  uint64 rdx{node_id};
  uint64 r8{0};
  uint64 r9[1]{0};
  uint64 args[10]{addr, rcx, rdx, r8, (uint64)r9};
  uint64 rax = send_call(args);
  if (rax > 0) {
    return (char *)(rax + r4(rax));
  }
  return "未知飞行点";
}

string Game::get_taxi_node_name(uint32 node_id) {
  uint64 base = base_ + RVA_TAXI_NODE_ARR_BASE;
  uint64 rcx = r8(base + 0x140);
  uint32 min_node_id = r4(rcx + 0x40);
  uint32 max_node_id = r4(rcx + 0x44);
  uint64 arr = r8(rcx + 0x80);
  uint64 size = r8(rcx + 0x88);
  if (node_id < min_node_id || node_id > max_node_id) {
    return "未知飞行点";
  }
  uint32 eax{0};
  for (auto i : views::iota(0u, size)) {
    uint64 ptr = arr + i * 4;
    if (r2(ptr) == (node_id - min_node_id)) {
      eax = r2(ptr + 4 + 2);
      uint64 rax = eax * r4(rcx + 0x38) + r8(rcx + 8);
      if (rax > 0) {
        return (char *)(rax + r4(rax));
      }
    }
  }
  return "未知飞行点";
}

void Game::take_taxi(uint32 index) {
  uint64 addr{base_ + RVA_TAKE_TAXI_CALL};
  uint64 rcx{index};
  uint64 args[10]{addr, rcx};
  send_call(args);
}
